﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WCS.Entities
{
    public static class BitHelper
    {
        //    /// <summary>
        //    /// Int16\Int32\Int64类型
        //    /// </summary>
        //    /// <returns>true 1\false 0的集合</returns>
        //    public static IEnumerable<bool> GetIntOfBitList<T>(T intVal)
        //    {
        //        Type intType = intVal.GetType();
        //        byte bitlength = 0;
        //        if (intType == typeof(Int32))
        //            bitlength = 32;
        //        else if (intType == typeof(Int16))
        //            bitlength = 16;
        //        else if (intType == typeof(Int64))
        //            bitlength = 64;
        //        else
        //            throw new ArgumentException("必须是整型");

        //        object intOject = (object)intVal;
        //        var resultList = new List<bool>(bitlength);
        //        for (var i = 0; i < bitlength; i++)
        //        {
        //            var temoIntBit = 1 << i;
        //            if (intType == typeof(Int32))
        //                resultList.Add((((Int32)intOject) & temoIntBit) == temoIntBit);
        //            if (intType == typeof(Int16))
        //                resultList.Add((((Int16)intOject) & temoIntBit) == temoIntBit);
        //            if (intType == typeof(Int64))
        //                resultList.Add((((Int64)intOject) & temoIntBit) == temoIntBit);
        //        }
        //        return resultList;
        //    }


        //    /// <summary>
        //    /// 获取T整型中某一位的值
        //    /// </summary>
        //    /// <typeparam name="T">泛型类型包括int\short\long</typeparam>
        //    /// <param name="intVal">int\short\long</param>
        //    /// <param name="index">从右到左0-T的总位数</param>
        //    /// <returns>true:1\false:0</returns>
        //    public static bool GetBitValue<T>(T intVal, byte index)
        //    {
        //        Type intType = intVal.GetType();
        //        byte bitlength = 0;
        //        if (intType == typeof(Int32))
        //            bitlength = 32;
        //        else if (intType == typeof(Int16))
        //            bitlength = 16;
        //        else if (intType == typeof(Int64))
        //            bitlength = 64;
        //        else
        //            throw new ArgumentException("必须是整型");

        //        if (index > bitlength - 1 || index < 1)
        //            throw new ArgumentOutOfRangeException("index");

        //        object intOject = (object)intVal;
        //        var tempBit = 1 << index;

        //        if (intType == typeof(Int32))
        //            return (((int)intOject) & tempBit) == tempBit;
        //        else if (intType == typeof(Int16))
        //            return (((Int16)intOject) & tempBit) == tempBit;
        //        else
        //            return (((Int64)intOject) & tempBit) == tempBit;
        //    }


        //    /// <summary>
        //    /// 设置整型数据中某一位的值
        //    /// </summary>
        //    /// <typeparam name="T">int\short\long</typeparam>
        //    /// <param name="intVal">设置前的值</param>
        //    /// <param name="index">从右到左0-T的总位数</param>
        //    /// <param name="bitValue">需要设置的值 true:1\false:0</param>
        //    /// <returns>设置位值后新的整型</returns>
        //    public static dynamic SetBitValue<T>(T intVal, byte index, bool bitValue)
        //    {
        //        Type intType = intVal.GetType();
        //        byte bitlength = 0;
        //        if (intType == typeof(Int32))
        //            bitlength = 32;
        //        else if (intType == typeof(Int16))
        //            bitlength = 16;
        //        else if (intType == typeof(Int64))
        //            bitlength = 64;
        //        else
        //            throw new ArgumentException("必须是整型");
        //        //不能去设置最高位
        //        if (index >= bitlength - 1 || index < 1)
        //            throw new ArgumentOutOfRangeException("index");

        //        object intOject = (object)intVal;
        //        var tempBit = 1 << index;

        //        if (intType == typeof(Int32))
        //        {
        //            int tempInt = (int)intOject;
        //            return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
        //        }
        //        else if (intType == typeof(Int16))
        //        {
        //            Int16 tempInt = (Int16)intOject;
        //            return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
        //        }
        //        else
        //        {
        //            Int64 tempInt = (Int64)intOject;
        //            return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
        //        }
        //    }

        /// <summary>
        /// 根据Int类型的值，返回用1或0(对应True或Flase)填充的数组
        /// <remarks>从右侧开始向左索引(0~31)</remarks>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IEnumerable<bool> GetBitList(int value)
        {
            var list = new List<bool>();
            for (var i = 0; i <= 31; i++)
            {
                var val = 1 << i;
                list.Add((value & val) == val);
            }
            return list;
        }

        /// <summary>
        /// 返回Int数据中某一位是否为1
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index">32位数据的从右向左的偏移位索引(0~31)</param>
        /// <returns>true表示该位为1，false表示该位为0</returns>
        public static bool GetBitValue(int value, ushort index)
        {
            if (index > 31) throw new ArgumentOutOfRangeException("index"); //索引出错
            var val = 1 << index;
            return (value & val) == val;
        }

        /// <summary>
        /// 设定Int数据中某一位的值
        /// </summary>
        /// <param name="value">位设定前的值</param>
        /// <param name="index">32位数据的从右向左的偏移位索引(0~31)</param>
        /// <param name="bitValue">true设该位为1,false设为0</param>
        /// <returns>返回位设定后的值</returns>
        public static int SetBitValue(int value, ushort index, bool bitValue)
        {
            if (index > 31) throw new ArgumentOutOfRangeException("index"); //索引出错
            var val = 1 << index;
            return bitValue ? value | val : value & ~val;
        }

    }
}
